parser grammar AnalexParser;

options {
  language = Java;
  tokenVocab = AnalexLexer;
}

@header {
  package Practica6.Ambiguedad;
}

@members {
  boolean rompe = true;
  private ArrayList<String> errors = new ArrayList<String>();
  public void displayRecognitionError(String[] tokenNames, RecognitionException e) {
    String hdr = getErrorHeader(e);
    String msg = getErrorMessage(e, tokenNames);
    errors.add(hdr + " " + msg);
  }
   
  public ArrayList<String> getErrors() {
    return errors;
  }
} 
  
entrada: sentencia;
sentencia: (funcion)+;

funcion: funcion_cabecera (instruccion)* (return_statement)? RIGHT_BRACE;
funcion_cabecera: (DATO_TIPO|KEYWORD_VOID) ID LEFT_PAREN (parametros|KEYWORD_VOID) RIGHT_PAREN LEFT_BRACE;
funcion_instancia: ID LEFT_PAREN (valores|COMA valores)* RIGHT_PAREN;
parametros: (DATO_TIPO ID (COMA DATO_TIPO ID)*)*;
variable: (DATO_TIPO ID (COMA ID)*) SEPARADOR;
declaracion: DATO_TIPO asignacion;
asignacion: ID OP_ASSIGN expresion SEPARADOR;
inc_dec: ((ID OP_INC) | (ID OP_DEC));
pre_inc_dec: ((OP_INC ID) | (OP_DEC ID)) SEPARADOR;
valores: (STRING|NUMERO|ID|funcion_instancia);
return_statement: KEYWORD_RETURN (expresion)? SEPARADOR; 

bloque_while: KEYWORD_WHILE LEFT_PAREN expresion RIGHT_PAREN bloque;
bloque_if : KEYWORD_IF LEFT_PAREN expresion RIGHT_PAREN bloque; 
bloque_for: KEYWORD_FOR LEFT_PAREN ((variable|asignacion|declaracion)? | SEPARADOR) expresion? SEPARADOR inc_dec? RIGHT_PAREN bloque;

bloque: (instruccion| (LEFT_BRACE (instruccion)* RIGHT_BRACE)){ rompe = true;};
instruccion: (asignacion|inc_dec|pre_inc_dec|variable|(funcion_instancia SEPARADOR)|bloque_while|bloque_if|bloque_for|abort_bloque);
expresion: (OP_SUM|OP_SUB)? operacion (OP_QUESTIONMARK operacion OP_COLON operacion)?;
operacion: suma ((OP_SUM|OP_SUB) suma)*;
suma: producto ((OP_MULT|OP_DIV) producto)*;
producto: proposicion ((OP_AND|OP_OR) proposicion)*;
proposicion: (OP_EXCLA)? comparacion;
comparacion:  factor ((OP_MA|OP_MAI|OP_ME|OP_MEI|OP_IGUAL|OP_DISTINTO) factor)? ;
factor  : (CARACTER|NUMERO|ID) | (LEFT_PAREN expresion RIGHT_PAREN);
abort_bloque: {rompe}? KEYWORD_BREAK SEPARADOR { rompe = false;}; 